home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1995 April / Internet Tools.iso / infoserv / gopher / Unix / gopher-gateways / techinfo / techinpher / v1.0 / server.c.Z / server.c
Encoding:
C/C++ Source or Header  |  1993-02-23  |  17.7 KB  |  722 lines

  1. /*
  2.  *------------------------------------------------------------------
  3.  *
  4.  * $Source: /afs/net.mit.edu/dapps/project/techinfodev/src/srv_ti/RCS/server.c,v $
  5.  * $Revision: 1.6 $
  6.  * $Date: 92/08/28 16:09:47 $
  7.  * $State: Exp $
  8.  * $Author: ark $
  9.  * $Locker: ark $
  10.  *
  11.  * $Log:    server.c,v $
  12.  * Revision 1.6  92/08/28  16:09:47  ark
  13.  * Summer 1992 final version
  14.  * 
  15.  * Revision 1.5  92/08/12  14:18:26  ark
  16.  * New version of 'o' transaction tells what output format to use;
  17.  * this is a hack to allow old (but broken) clients to still work.
  18.  * 
  19.  * Revision 1.4  92/08/11  13:46:54  ark
  20.  * Bug fixes: 'n' transaction leaving file descriptors open;
  21.  *            'b' transaction now disallows searches on empty strings.
  22.  * 
  23.  * Revision 1.3  92/08/06  18:44:32  ark
  24.  * Admin command "B" no longer crashes when there are many connections.
  25.  * 
  26.  * Revision 1.2  92/08/04  16:28:12  ark
  27.  * Test production version 8/4/92
  28.  * 
  29.  * Revision 1.1  92/07/22  11:09:29  ark
  30.  * Saber loads quietly; ANSI use standardized; command line options; no behavioral changes
  31.  * 
  32.  * Revision 1.0  92/07/10  12:34:00  ark
  33.  * Initial revision
  34.  * 
  35.  * Revision 1.1  91/07/15  10:40:39  thorne
  36.  * Initial revision
  37.  * 
  38.  *------------------------------------------------------------------
  39.  */
  40.  
  41. #ifndef lint
  42. #ifndef SABER
  43. static char *rcsid_foo_c = "$Header: /afs/net.mit.edu/dapps/project/techinfodev/src/srv_ti/RCS/server.c,v 1.6 92/08/28 16:09:47 ark Exp Locker: ark $";
  44. #endif
  45. #endif  lint
  46.  
  47. /*
  48.  * server.c 
  49.  * S. Thorne
  50.  * This is the entry point of the Techinfo server. It loads the web and gets
  51.  * connections. It contains the main server loop.
  52.  */
  53. /*
  54.   Copyright (C) 1989 by the Massachusetts Institute of Technology
  55.  
  56.    Export of this software from the United States of America is assumed
  57.    to require a specific license from the United States Government.
  58.    It is the responsibility of any person or organization contemplating
  59.    export to obtain such a license before exporting.
  60.  
  61. WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
  62. distribute this software and its documentation for any purpose and
  63. without fee is hereby granted, provided that the above copyright
  64. notice appear in all copies and that both that copyright notice and
  65. this permission notice appear in supporting documentation, and that
  66. the name of M.I.T. not be used in advertising or publicity pertaining
  67. to distribution of the software without specific, written prior
  68. permission.  M.I.T. makes no representations about the suitability of
  69. this software for any purpose.  It is provided "as is" without express
  70. or implied warranty.
  71.  
  72. */
  73.  
  74. #include <stdio.h>
  75. #include <errno.h>
  76. #include <sys/types.h>
  77. #include <sys/time.h>
  78. #include <sys/file.h>
  79. #include <signal.h>
  80. #include <strings.h>
  81. #include "network.h"
  82. #include "inet.h"
  83. /*#include "web.h" */
  84. #include "pdb.h"  
  85. /* #include <unistd.h>  Ulriix ??? */
  86.  
  87. CONN            conntab[FD_SETSIZE];
  88.  
  89. fd_set   read_fds;
  90. fd_set   write_fds;
  91. fd_set   except_fds;
  92.  
  93. #define    sock_readable(s)    FD_ISSET(s, &read_fds)
  94.  
  95. #define    conn_writeable(cn)    FD_ISSET(conntab[cn].c_socket,&write_fds)
  96. #define    conn_except(cn)            FD_ISSET(conntab[cn].c_socket,&except_fds)
  97. #define    conn_readable(cn)    sock_readable(conntab[cn].c_socket)
  98. #define    conn_established(cn)    (conntab[cn].c_socket != -1)
  99. #define conn_wait_write(cn)      (conntab[cn].c_ptr) /* is the connection 
  100.                             waiting for data? */
  101. #define conn_wait_recv(cn)      (conntab[cn].c_recptr) /* is the connection 
  102.                             sending a file over? */
  103. #define    conn_timedout(cn)    (conntab[cn].c_flags & C_TIMEOUT) 
  104. #define    conn_provider(cn)    (conntab[cn].c_flags & C_PROVIDER) 
  105.  
  106. #define    POLL    &tv
  107. #define BLOCK    0
  108.  
  109. #define ADAY 86400  /* this should go in a .h file, but which? -- lam */
  110.  
  111. static int      num_connection;
  112. static int      listen_sock;
  113. int             PENDING_SHUTDOWN  = FALSE;
  114. int             ALT_BANNER = FALSE;
  115. char            *shutdown_msg;
  116. char            *alt_banner;
  117. short           todaysdate = 0;  /* will be properly initialized later */
  118. static int      alarmwentoff;
  119.  
  120. extern int  datastruct_load(int unloadfirst);
  121. extern void save_datastruct(void);
  122. extern void remove_send(TOSEND *ptr);
  123. extern void remove_rec(TOREC *ptr);
  124. extern void remove_helper(WAITFORHELPER *ptr);
  125. extern void log_trans(char *str);
  126. extern void nio_rec_more(TOREC *ptr); 
  127. extern void catch_child(void);
  128. extern void catch_hup(void);
  129.  
  130. extern int      PROV; /* the socket # of the current provider */
  131. char *msglist[100];
  132. int    debug = 0; /* no debugging is default */
  133.  
  134.  
  135. void catch_alarm(void)
  136. {
  137.   alarmwentoff = 1;
  138. }
  139.  
  140.  
  141.  
  142. /* load the file of error messages. error file has structure of
  143.    <error #>:<error text> */
  144. int
  145. load_msgs(void) 
  146. {
  147.  
  148.     FILE           *fopen(), *msgfile;
  149.         char      msgline[101];
  150.         int pos = 0;
  151.         int len;
  152.  
  153.     msgfile = fopen(MSG_FILE, "r");
  154.     if (!msgfile) {
  155.         perror(MSG_FILE);
  156.         puts("Could not find the message file");
  157.         exit(1);
  158.     }
  159.     while (fgets(msgline, 100, msgfile) != '\0') {
  160.       len = strlen(msgline);
  161.       msgline[len - 1] = '\0';
  162.       msglist[pos] = (char *) domalloc((unsigned int) len);
  163.       strcpy(msglist[pos],msgline);
  164.       pos++;
  165.     }
  166.     fclose(msgfile);
  167.     return 0;        /* close file */
  168.  
  169. }
  170.  
  171. /* write the transaction to the log file */
  172. void
  173. log_session(char *line)            
  174. {
  175.     int dfd;
  176.     if ((dfd = open(LOG_FILE, O_APPEND | O_CREAT | O_WRONLY, 0644)) == 0)
  177.         printf("error logging transaction\n");
  178.     write(dfd, line, strlen(line));
  179.     close(dfd);
  180.     return;
  181. }
  182.  
  183. void
  184. dump_conntab(void)
  185. {
  186.   int i,fd;
  187.   char line[200];
  188.   
  189.   fd = open("conntab",O_CREAT|O_TRUNC|O_WRONLY, 0644);
  190.   for (i = 0; i < FD_SETSIZE; i++) {
  191.     if (conn_established(i)){
  192.       sprintf(line,"conn # %d, sock = %d, hostname = %s\n",i,conntab[i].c_socket,
  193.           conntab[i].c_hostname);
  194.       write(fd,line,strlen(line));}
  195.   }
  196.   close(fd);
  197. }
  198.  
  199. /* Close the connection on socket c, saving the web if it was connected to
  200.    a provider.
  201.    Note: Should there be a modified flag in the provider's socket info to
  202.          determine whether or not we need to save the web? 
  203. */
  204. void
  205. close_connection(int c)
  206. {
  207.     time_t          secs;
  208.     char       line[120];
  209.     int rc;
  210.  
  211.     time(&secs);
  212.     if (debug) {
  213.       printf("Closing connection to %s, port %d, socket #%d.\n",
  214.          conntab[c].c_hostname,
  215.          conntab[c].c_portnum,
  216.          conntab[c].c_socket);
  217.       fflush(stdout);
  218.     }
  219.  
  220.     sprintf(line,"%d %d %s  %.24s, active %.1f minutes - SERVER\n",
  221.         conntab[c].c_portnum,
  222.         conntab[c].c_socket,
  223.         conntab[c].c_hostname,
  224.         ctime(&secs),
  225.         (float) ((secs - conntab[c].c_made) /60.0));
  226.     log_session(line);
  227.     if (conntab[c].c_ptr != NULL)
  228.       remove_send(conntab[c].c_ptr);
  229.     if (conntab[c].c_recptr != NULL)
  230.       remove_rec(conntab[c].c_recptr);
  231.     if (conntab[c].c_hptr != NULL)
  232.       remove_helper(conntab[c].c_hptr); /* send KILL to child */
  233.  
  234.     do_free(conntab[c].c_hostname);
  235.     do_free(conntab[c].c_uid);
  236.     do_free(conntab[c].c_type);
  237.     FD_CLR(conntab[c].c_socket, &read_fds); /* not needed now ? */
  238.     FD_CLR(conntab[c].c_socket, &write_fds);
  239.     FD_CLR(conntab[c].c_socket, &except_fds);
  240.     rc = close(conntab[c].c_socket);
  241.     if (rc < 0) {
  242.       sprintf(line,"Connection close failed on socket %d\n",conntab[c].c_socket);
  243.       printf(line); fflush(stdout);
  244.       log_session(line);
  245.     }
  246.     conntab[c].c_socket = -1;
  247.     conntab[c].c_ptr = NULL;
  248.     conntab[c].c_recptr = NULL;
  249.     conntab[c].c_hptr = NULL;
  250.     num_connection--;
  251. }
  252.  
  253.  
  254. /*
  255.  * Find the connection using the given socket, and mark it as having
  256.  * timed out, so the server can close it off next time around.
  257.  */
  258.  
  259. void
  260. sock_timeout(int sock)
  261. {
  262.     int    i;
  263.  
  264.     for (i = 0; i < FD_SETSIZE; i++) {
  265.         if (conntab[i].c_socket == sock) {
  266.             conntab[i].c_flags |= C_TIMEOUT;
  267.             break;
  268.         }
  269.     }
  270.     printf("Sock #%d marked for timeout termination.\n",
  271.         conntab[i].c_socket);
  272.     fflush(stdout);
  273. }
  274.  
  275. void
  276. server_shutdown()
  277. {
  278.     int             i;
  279.  
  280.     save_datastruct();    /* do this for production only? */
  281.     log_trans("Shuting down the server");
  282.     puts("\nServer shutdown, closing connections:");
  283.  
  284.     for (i = 0; i < FD_SETSIZE; i++)    /* Close Connections */
  285.         if (conn_established(i))
  286.             close_connection(i);
  287.  
  288.     close(listen_sock);  
  289.     puts("Server has shut down -- Exiting.");
  290.     exit(0);
  291. }
  292.  
  293. int
  294. hdl_connect(int c)
  295. {
  296.     CONN           *conn = &conntab[c];
  297.     int             quit;
  298.  
  299.     if (debug) {
  300.       printf("\nHandling transaction to %s, port %d, socket #%d.\n",
  301.          conn->c_hostname,
  302.          conn->c_portnum,
  303.          conn->c_socket);
  304.       fflush(stdout);
  305.     }
  306.  
  307.     quit = hdl_transact(conn);
  308.     time(&conn->c_last);
  309.  
  310.     return quit;
  311. }
  312.  
  313. void
  314. make_new_connection(int listen_sock)
  315. {
  316.     CONN           *conn;
  317.     char           *hostname,line[100],*cp;
  318.     int            i;
  319.     time_t    secs;
  320.     time(&secs);
  321.     for (i = 0; i < FD_SETSIZE; i++)
  322.       if (!conn_established(i))
  323.         break;
  324.     if (i == FD_SETSIZE) {
  325.       printf("TechInfo server: reached connection limit of %d.\n",
  326.          FD_SETSIZE);
  327.       fflush(stdout);
  328.       return;
  329.     }
  330.     conn = &conntab[i];
  331.  
  332.     conn->c_socket = inet_accept_connection(listen_sock, &hostname,
  333.                         &conn->c_portnum);
  334.  
  335.     if (conn->c_socket == -1) {
  336.         puts("accept_connection failed");
  337.         return;
  338.     }
  339.     if (PENDING_SHUTDOWN) /* don't accept new connections */
  340.       {  /* send alternate message and close connection down */
  341.         if (shutdown_msg) 
  342.           {
  343.         write(conn->c_socket, shutdown_msg, strlen(shutdown_msg));
  344.         write(conn->c_socket, EOM, EOM_LEN);
  345.           }
  346.         else 
  347.           {
  348.         write(conn->c_socket, NAK_BANNER, strlen(NAK_BANNER));
  349.         write(conn->c_socket, EOM, EOM_LEN);
  350.           }
  351.         /* possibly sleep ?? */
  352.         close(conn->c_socket);
  353.         conn->c_socket = -1;
  354.         return;
  355.       }
  356.     conn->c_hostname = (char *) domalloc((unsigned int) strlen(hostname) + 1);
  357.     strcpy(conn->c_hostname, hostname);
  358.     conn->c_uid = (char *) domalloc((unsigned int) 25);
  359.     *conn->c_uid = '\0';
  360.     conn->c_flags = 0;
  361.     conn->c_type = NULL;
  362.     conn->c_last = time(&conn->c_made);
  363.     conn->c_ptr = NULL;
  364.     conn->c_recptr = NULL;
  365.     conn->c_hptr = NULL;
  366.     conn->c_trans_cnt = 0;
  367.     /* Added 8/12/92 ark -- Set initial output format to that defined in network.h
  368.        Change with the 'o' transaction */
  369.     conn->c_output_fmt = DEFAULT_OUTPUT_FORMAT;
  370.  
  371.     num_connection++;
  372.     if (debug) {
  373.       printf("Accepted new connection to %s, thru port %d, over socket #%d.\n",
  374.            conn->c_hostname,
  375.            conn->c_portnum,
  376.            conn->c_socket);
  377.       fflush(stdout);
  378.     }
  379.     if (ALT_BANNER) {
  380.       write(conn->c_socket, alt_banner, strlen(alt_banner));
  381.       write(conn->c_socket, EOM, EOM_LEN);
  382.     }
  383.     else {
  384.       write(conn->c_socket, BANNER, strlen(BANNER));
  385.       write(conn->c_socket, EOM, EOM_LEN);
  386.     }
  387.  
  388.     if (fcntl(conn->c_socket, F_SETFL, FNDELAY) == -1)
  389.         perror("fcntl");
  390.  
  391.     /*
  392.      * We should turn blocking on BEFORE write the banner!  Those
  393.      * writes shouldn't be direct syscalls either.
  394.      */
  395.     if (conn->c_type == NULL)
  396.       cp = "unknown";
  397.     else
  398.       cp = conn->c_type;
  399.     sprintf(line,"%d %d %s %s %.24s - SERVER\n",
  400.         conn->c_portnum,
  401.         conn->c_socket,
  402.         conn->c_hostname,
  403.             cp,
  404.         ctime(&secs));
  405.     log_session(line);
  406.         
  407. }
  408.  
  409. int             Standalone = 1;
  410.  
  411. static    int             i, handled;
  412. static    time_t          secs;
  413.  
  414. int    ActiveJobs = 0;        /* Number of pending sends & recvs 
  415.                  set int netio.c */
  416.  
  417. static    CONN        *conn;
  418.  
  419. extern int max_stale_time; /* in shutdown mode wait until all conn have been 
  420.                   inactive for this many minutes */
  421. void
  422. server_loop(void)
  423. {
  424.   int        active_socks, show_connect = 0, do_shutdown;
  425.   char line[200];
  426.   struct timeval    tv;
  427.   
  428.   tv.tv_sec = 0;        /* For our select when it only polls */
  429.   tv.tv_usec = 0;
  430.  
  431.   alarmwentoff = 1;
  432.   signal (SIGALRM, catch_alarm);
  433.  
  434.   for (;;) {
  435.     if (alarmwentoff) {
  436.       alarmwentoff = 0;
  437.       save_datastruct();
  438.       alarm(60);   /* set alarm for 1 minute */
  439.     }
  440.  
  441.     if (PENDING_SHUTDOWN)
  442.       do_shutdown = TRUE;
  443.     if (!ActiveJobs)
  444.       show_connect++;
  445.     if (show_connect && debug && num_connection) {
  446.       printf("\nCurrent connections:");
  447.       fflush(stdout);
  448.     }
  449.     FD_ZERO(&read_fds);
  450.     FD_ZERO(&write_fds);
  451.     FD_ZERO(&except_fds);
  452.     FD_SET(listen_sock, &read_fds);
  453.     time(&secs);
  454.     for (i = 0; i < FD_SETSIZE; i++) {
  455.       if (!conn_established(i))
  456.     continue;
  457.       conn = &conntab[i];
  458.       if (conn_wait_write(i))
  459.     FD_SET(conn->c_socket, &write_fds); 
  460.       else
  461.     FD_SET(conn->c_socket, &read_fds);
  462.       FD_SET(conn->c_socket, &except_fds);
  463.       
  464.       if (!show_connect)
  465.     continue;
  466.       if (debug) {
  467.     printf("\n#%2d  %s.%d\tactive %.1f, last %.1f",
  468.            conn->c_socket,
  469.            conn->c_hostname,
  470.            conn->c_portnum,
  471.            (float) (secs - conn->c_made) / 60.0,
  472.            (float) (secs - conn->c_last) / 60.0);
  473.     fflush(stdout);
  474.       }
  475.       if (conn->c_ptr != NULL | conn->c_recptr != NULL) {
  476.     if (((secs - conn->c_last) / 60.0) > 30.0)
  477.       close_connection(i);   /* this conn asked for something 30 minutes
  478.                     ago and still hasn't gotten it... */
  479.       } 
  480.       if (PENDING_SHUTDOWN)
  481.     if  (((secs - conn->c_last) / 60.0) < max_stale_time)
  482.       do_shutdown = FALSE;
  483.       if (((secs - conn->c_last) / 60.0) > 700.0)
  484.      close_connection(i);  /* close connections which
  485.                   timed out */
  486.     }
  487.     
  488.     if (PENDING_SHUTDOWN && do_shutdown)
  489.       server_shutdown();
  490.     if (show_connect && debug) {
  491.       if (num_connection) {
  492.     printf("\n%d connection%s currently established.\n",
  493.            num_connection, num_connection == 1 ? "" : "s");
  494.     fflush(stdout);
  495.       }
  496.       /*      else
  497.           puts(" None"); */
  498.     }
  499.     if (debug) {
  500.       if (ActiveJobs)
  501.     printf("%s for activity...",
  502.            ActiveJobs ? "Checking" : "Waiting");
  503.       if (ActiveJobs)
  504.     printf("(%d asleep)...", ActiveJobs);
  505.       fflush(stdout);
  506.     }
  507.     show_connect = 0;
  508.     
  509.     
  510.     active_socks = select(FD_SETSIZE,&read_fds, &write_fds, 
  511.               &except_fds,
  512.               BLOCK);
  513.     
  514.     if (active_socks < 0) {
  515.       if (errno != EINTR)
  516.     perror("select");
  517.       continue;
  518.     }
  519.     if (debug) {
  520.       if (!active_socks && ActiveJobs) {
  521.     printf("none...continuing our %d active processes...\n",
  522.            ActiveJobs);
  523.     continue;
  524.       }
  525.       
  526.       
  527.       printf("%d socket%s reported with new activity.\n",
  528.          active_socks, active_socks == 1 ? "" : "s");
  529.       fflush(stdout);
  530.     }
  531.     handled = 0;
  532.     
  533.     /*
  534.      * First, see if we can establish any new connections. Takes
  535.      * only first one off queue even if there are more. 
  536.      */
  537.     
  538.     if (sock_readable(listen_sock))
  539.       {
  540.     make_new_connection(listen_sock);
  541.     handled++;
  542.     show_connect++;
  543.       }
  544.     
  545.     /*
  546.      * Now handle requests from all connections that have sent
  547.      * them. 
  548.      */
  549.  
  550.     todaysdate = time(0) / ADAY;  /* outside loop; used by other modules */
  551.  
  552.     for (i = 0; i < FD_SETSIZE; i++) {
  553.       if (!conn_established(i))
  554.     continue;
  555.       if (conn_timedout(i)) {
  556.     if (conn_readable(i))
  557.       handled++;
  558.         close_connection(i), show_connect++;
  559.     continue;
  560.       }
  561.       if (conn_except(i)) {
  562.     printf("Exceptional condition on socket %d, closing connection.\n", i);
  563.     fflush(stdout);
  564.     handled++;
  565.     close_connection(i);
  566.     continue;
  567.       }
  568.       
  569.       if (conn_wait_recv(i)){ /* if we're in the middle of
  570.                  getting a file */
  571.     nio_rec_more(conntab[i].c_recptr);
  572.     handled++;
  573.     continue;
  574.       }
  575.       else if (conn_writeable(i)) 
  576.     { /* finish writing */
  577.       handled++;
  578.       send_more(conntab[i].c_ptr);
  579.     }
  580.       else if (conn_readable(i))
  581.     {
  582.       handled++;
  583.  
  584.       if (hdl_connect(i) || conntab[i].c_trans_cnt > MAX_TRANS)
  585.         {
  586.         close_connection(i), show_connect++;
  587.         if (conntab[i].c_trans_cnt > MAX_TRANS) {
  588.           sprintf(line,"MAX TRANS REACHED... closing sock %d - %s\n",
  589.               conntab[i].c_socket,conntab[i].c_hostname);
  590.           log_session(line);
  591.         }
  592.       }
  593.       continue;
  594.     }
  595.     }
  596.     
  597.     /*
  598.      * We have a very major problem if we thought we needed to do
  599.      * something, and nothing was done, cause this can mean we're
  600.      * headed into an infinte loop.  So we close everyone off if
  601.      * this happens (although it never should...) 
  602.      */
  603.     
  604.     if (!handled) {
  605.       fprintf(stderr, "TechInfo server: Very major client plexing problem.\n");
  606.       for (i = 0; i < FD_SETSIZE; i++)
  607.     if (conn_established(i))
  608.       close_connection(i);
  609.     }
  610.   }
  611. }
  612.  
  613. void
  614. broken_pipe()
  615. {
  616.     puts("SIGPIPE - No one to read our write.");
  617.     close_connection(i);
  618. }
  619.  
  620. main(int argc, char **argv)
  621. {
  622.  
  623.     extern int    menu;
  624.     extern int    disptype;
  625.     int pips_port = PIPS_PORT;
  626.  
  627.     char c;
  628.     int errorflag = 0, temp_port = 0;
  629.     extern int optind;
  630.     extern char *optarg;
  631.  
  632.     
  633.     while ((c = getopt(argc, argv, "dp:")) != EOF)
  634.       switch (c) {
  635.       case 'd':
  636.         debug++;
  637.         break;
  638.       case 'p':
  639.         if (optarg)          
  640.           temp_port = atoi(optarg);
  641.         break;
  642.       default:
  643.         errorflag++;
  644.       }
  645.     if (errorflag)
  646.       {
  647.         printf("Usage: %s [-p port] [-d]\n", argv[0]);
  648.         exit(1);
  649.       }
  650.  
  651.     if (temp_port)
  652.       if (temp_port > 1000)
  653.         pips_port = temp_port;
  654.       else 
  655.         {
  656.           puts("Must use a port number greater than 1000");
  657.           exit(1);
  658.         }
  659.     
  660.  
  661.       menu = NOMENU;
  662.     disptype = SIMPLE;
  663.     setuid(SERVER_UID); /* ti_serve */
  664.     printf("Uid set to %d\n",getuid());
  665.     if (access(PROV_FILE, F_OK)) {
  666.         puts("Could not find the provider file");
  667.         exit(1);
  668.     }
  669.     if (access(ADMIN_FILE, F_OK)) {
  670.         puts("Could not find the admin file");
  671.         exit(1);    
  672.           }
  673.     if (access(NEXTID_FILE, F_OK)) {
  674.         puts("Could not find the next_id file");
  675.         exit(1);    
  676.           }
  677.     if (access(VER_FILE, F_OK)) {
  678.         puts("Could not find the version file");
  679.         exit(1);    
  680.           }
  681.     if (access(SOURCE_FILE, F_OK)) {
  682.         puts("Could not find the source file");
  683.         exit(1);    
  684.           }
  685.     if (access(SERVER_FILE, F_OK)) {
  686.         puts("Could not find the server file");
  687.         exit(1);    
  688.           }
  689.     for (i = 0; i < FD_SETSIZE; i++)
  690.         conntab[i].c_socket = -1;    
  691.     signal(SIGINT, server_shutdown);
  692.     signal(SIGTERM, server_shutdown);
  693.     signal(SIGCHLD, catch_child);
  694.     signal(SIGHUP, catch_hup);
  695.     SERVER = TRUE;
  696.     printf("\n%s\n", BANNER); fflush(stdout);
  697.     time(&secs);
  698.     load_msgs(); /* load the message list from disk */
  699.     printf("Started %.24s, pid = %d\n\n", ctime(&secs), getpid());
  700.     fflush(stdout);
  701.  
  702.     listen_sock = inet_make_listner(pips_port);
  703.     if (listen_sock < 0) {
  704.         puts("Unable to accept connections!");
  705.         exit(1);
  706.     }
  707.     if (!(int) datastruct_load(0)) {
  708.         puts("Fatal error: datastruct_load failed");
  709.         exit(1);
  710.     }
  711.  
  712.     FD_ZERO(&read_fds);
  713.     log_trans("Starting server");
  714.     printf("TechInfo server ready.\n"); fflush(stdout);
  715.     num_connection = 0;
  716.     signal(SIGPIPE, broken_pipe);
  717.     umask(022);
  718.  
  719.     fflush(stdout);
  720.     server_loop();
  721. }
  722.